/*
	Chip is an auxillary class for an array of containers. The containers of each chip are meant for a specific threads work group.
	The term 'permutation' in this context is a thread-local permutation of the containers that determines the order of access 
	of the threads to the containers in the array.
*/
#ifndef CHIP_H_
#define CHIP_H_
#include "TaskContainer.h"
#include "ConcurrentListContainer.h"
#include "WorkStealingContainer.h"
#include <time.h>

class Chip{
	/* determines the number of traversals over the containers array a thread completes before it generates a new permutation */
	static const int permutationRefreshRate = 500;
	
	/* array of containers */
	TaskContainer** containers;
	
	/* number of containers */
	int containersNum;
	
	/* thread-local permutation of the containers in the array */
	static __thread int* permutation;
	
	/* thread-local variable that holds the number of traversals over the containers array since the last permutation refresh */
	static __thread int traversalsNum;
	
	/* current container - last container accessed by the thread through getRandomContainer */
	static __thread int currContainer;
	
	/* current container - accessed by the thread either through getRandomContainer() or while traversing the containers in getNextContainer() */
	static __thread int currIter;
	
	//static __thread int nextContainer;
	
	/* a thread-local thread indicating whether the initial permutation is used */
	static __thread bool originalPermutation;
	
	/* initial permutation. The same for all threads */
	int* initialPermutation;
	
	static __thread bool hasRandomSeed;
public:
	/* constructor */
	Chip(string containerType, int containersNum, int maxConsumers);
	
	/* generate a new permutation of the containers in the array (a permutation of 0,1,...,containersNum-1) */
	int* generatePermutation();
	
	/* return a random container */
	TaskContainer* getRandomContainer();
	
	/* returns the next container in a traversal over the containers array according to the order determined by permutation.
		If a traversal has been completed (returned to the container from which it started - currContainer),
		a new permitation is generated and NULL is returned */
	TaskContainer* getNextContainer();
	
	/* register consumer to all the containers in the array */
	void registerConsumer(int tid);
	
	/* register producer to all the containers in the array */
	void registerProducer(int tid);
	
	// void setConsumersNum(int consumersNum);
	
	/* destructor */
	virtual ~Chip();
};
#endif